package com.woniu108.order.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.ObjectUtil;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniu108.carService.commos.dto.*;
import com.woniu108.carService.commos.exception.WoniuException;
import com.woniu108.carService.commos.exception.car.CarException;
import com.woniu108.carService.commos.exception.car.CarExceptionCode;
import com.woniu108.carService.commos.exception.orderProduct.OrderProductException;
import com.woniu108.carService.commos.exception.orderProduct.OrderProductExceptionCode;
import com.woniu108.carService.commos.exception.orderService.OrderServiceException;
import com.woniu108.carService.commos.exception.orderService.OrderServiceExceptionCode;
import com.woniu108.carService.commos.model.PagePayParam;
import com.woniu108.carService.commos.model.Result;
import com.woniu108.carService.commos.util.AlipayConfiguration;
import com.woniu108.carService.commos.util.AlipayUtil;
import com.woniu108.carService.commos.util.StaticData;
import com.woniu108.order.client.*;
import com.woniu108.order.mapper.OrderServiceInfoMapper;
import com.woniu108.order.mapper.OrderServiceMapper;
import com.woniu108.order.model.dto.OrderServiceDto;
import com.woniu108.order.model.dto.OrderServiceInfoDto;
import com.woniu108.order.model.form.GetOneUserForm;
import com.woniu108.order.model.form.ServiceAndProductListForm;
import com.woniu108.order.model.model.OrderService;
import com.woniu108.order.model.model.OrderServiceInfo;
import com.woniu108.order.model.param.OrderServiceAddParam;
import com.woniu108.order.model.param.OrderServiceQueryConditionParam;
import com.woniu108.order.model.param.OrderServiceQueryConditionToStoreAdminParam;
import com.woniu108.order.service.OrderServiceInfoService;
import com.woniu108.order.service.OrderServiceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniu108.product.form.FailedSaleForm;
import com.woniu108.product.form.OutStorageForm;
import com.woniu108.product.form.PutStorageForm;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * <p>
 * 服务订单 服务实现类
 * </p>
 *
 * @author yanxi
 * @since 2024-05-23
 */
@Service
public class OrderServiceServiceImpl extends ServiceImpl<OrderServiceMapper, OrderService> implements OrderServiceService {
    @Resource
    private OrderServiceMapper orderServiceMapper;
    @Resource
    private OrderServiceInfoMapper orderServiceInfoMapper;
    @Resource
    private PersonClient personClient;
    @Resource
    private ValueAddedClient valueAddedClient;
    @Resource
    private ProductClient productClient;
    @Resource
    private CarClient carClient;
    @Resource
    private ExtraClient extraClient;
    @Resource
    private OrderServiceInfoService orderServiceInfoService;
    @Resource
    private AlipayUtil alipayUtil;
    @Resource
    private AlipayConfiguration alipayConfiguration;
    @Resource
    private RabbitTemplate rabbitTemplate;

    @Override
    public Page<OrderServiceDto> selectOrderServicesByCondition(OrderServiceQueryConditionParam param) {
        QueryWrapper<OrderService> queryWrapper = new QueryWrapper<>();

        //根据phone，nickName，realName查询用户信息
        UserInfoDto userInfoDto = new UserInfoDto();
        if (!param.getUserNickName().isEmpty() || !param.getUserRealName().isEmpty() || !param.getUserPhone().isEmpty()) {
            Result<UserInfoDto> userInfoDtoResult = personClient.getOneUser(BeanUtil.toBean(param, GetOneUserForm.class));
            if (userInfoDtoResult.getCode() != 200) {
                throw new OrderProductException(500, "角色信息报错");
            }
            userInfoDto = userInfoDtoResult.getData();
            param.setUserId(userInfoDto.getUserId());
        }

        //按下单时间查询
        if (ObjectUtil.isNotEmpty(param.getOrderMinTime())) {
            queryWrapper.gt("order_time", DateUtil.parse(param.getOrderMinTime(), "yyyy-MM-dd HH:mm:ss"));
        }
        if(ObjectUtil.isNotEmpty(param.getOrderMaxTime())){
            queryWrapper.le("order_time",DateUtil.parse(param.getOrderMaxTime(), "yyyy-MM-dd HH:mm:ss"));
        }
        if (ObjectUtil.isNotEmpty(param.getPayMinTime())) {
            queryWrapper.gt("pay_time",DateUtil.parse(param.getPayMinTime(), "yyyy-MM-dd HH:mm:ss"));
        }
        if(ObjectUtil.isNotEmpty(param.getPayMaxTime())){
            queryWrapper.le("pay_time",DateUtil.parse(param.getPayMaxTime(), "yyyy-MM-dd HH:mm:ss"));
        }

        if (!param.getUserId().isEmpty()) {
            queryWrapper.eq("user_id", param.getUserId());
        }
        if (!param.getOrderServiceNum().isEmpty()) {
            queryWrapper.like("order_service_num", param.getOrderServiceNum());
        }
        if (param.getOrderServiceState() != null) {
            queryWrapper.eq("order_service_state", param.getOrderServiceState());
        }

        Page<OrderService> page = new Page<>(param.getPageNum(), param.getPageSize());
        orderServiceMapper.selectPage(page, queryWrapper);

        Page<OrderServiceDto> dtoPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
        ArrayList<OrderServiceDto> orderServiceDtos = new ArrayList<>();
        if (page.getRecords() != null) {
            for (OrderService orderService : page.getRecords()) {
                OrderServiceDto orderServiceDto = BeanUtil.toBean(orderService, OrderServiceDto.class);
                //用户信息
                Result<UserInfoDto> userInfoDtoResult = personClient.getByUserId(orderServiceDto.getUserId());
                if (userInfoDtoResult.getCode() != 200) {
                    throw new OrderProductException(userInfoDtoResult.getCode(), userInfoDtoResult.getMsg());
                }
                UserInfoDto dto = userInfoDtoResult.getData();
                orderServiceDto.setUserInfoDto(dto);
                //门店信息
                Result<StoreDto> storeDtoResult = personClient.getStoreById(orderServiceDto.getStoreId());
                if(storeDtoResult.getCode()!=200){
                    throw new WoniuException(userInfoDtoResult.getMsg(), userInfoDtoResult.getCode());
                }
                StoreDto storeDto = storeDtoResult.getData();
                orderServiceDto.setStoreDto(storeDto);
                //服务详情
                List<OrderServiceInfoDto> orderServiceInfoDtos = orderServiceInfoService.selectOrderServiceInfoByOrderServiceNum(orderServiceDto.getOrderServiceNum());
                orderServiceDto.setOrderServiceInfoDtos(orderServiceInfoDtos);
                //获取car信息
                Result<List<CarInfoDto>> listResult = carClient.loadCarInfoById(orderService.getUserId());
                if(listResult.getCode()!=200){
                    throw new WoniuException(listResult.getMsg(),listResult.getCode());
                }
                List<CarInfoDto> carInfoDtos = listResult.getData();
                if(carInfoDtos.size()>0){
                    for (CarInfoDto carInfoDto:carInfoDtos){
                        if(carInfoDto.getCarId().equals(orderServiceDto.getCarId())){
                            orderServiceDto.setCarInfoDto(carInfoDto);
                        }
                    }
                }else {
                    orderServiceDto.setCarInfoDto(null);
                }
                //
                orderServiceDtos.add(orderServiceDto);
            }
            dtoPage.setRecords(orderServiceDtos);
        }
        return dtoPage;
    }

    @Override
    public Page<OrderServiceDto> selectOrderServicesByConditionToStore(OrderServiceQueryConditionToStoreAdminParam param) {
        //固定查询门店订单
        QueryWrapper<OrderService> queryWrapper = new QueryWrapper<>();
        Result<StoreAdminDto> adminDtoResult = personClient.getStoreAdminInfoById(param.getStoreAdminId());
        if (adminDtoResult.getCode() != 200) {
            throw new OrderServiceException(adminDtoResult.getCode(), adminDtoResult.getMsg());
        }
        StoreAdminDto adminDto = adminDtoResult.getData();
        queryWrapper.eq("store_id", adminDto.getStoreId());

        //根据phone，nickName，realName查询用户信息
        UserInfoDto userInfoDto = new UserInfoDto();
        if (!param.getUserNickName().isEmpty() || !param.getUserRealName().isEmpty() || !param.getUserPhone().isEmpty()) {
            Result<UserInfoDto> userInfoDtoResult = personClient.getOneUser(BeanUtil.toBean(param, GetOneUserForm.class));
            if (userInfoDtoResult.getCode() != 200) {
                throw new OrderProductException(500, userInfoDtoResult.getMsg());
            }
            userInfoDto = userInfoDtoResult.getData();
        }

        //按下单时间查询
        if (!param.getOrderMaxTime().isEmpty() || !param.getOrderMinTime().isEmpty()) {
            queryWrapper.between("order_time", param.getOrderMinTime().isEmpty() ? null : DateUtil.parse(param.getOrderMinTime(), "yyyy-MM-dd HH:mm:ss").toString(), param.getOrderMaxTime().isEmpty() ? null : DateUtil.parse(param.getOrderMaxTime(), "yyyy-MM-dd HH:mm:ss").toString());
        }
        if (!param.getPayMaxTime().isEmpty() || !param.getPayMinTime().isEmpty()) {
            queryWrapper.between("pay_time", param.getPayMinTime().isEmpty() ? null : DateUtil.parse(param.getPayMinTime(), "yyyy-MM-dd HH:mm:ss").toString(), param.getPayMaxTime().isEmpty() ? null : DateUtil.parse(param.getPayMaxTime(), "yyyy-MM-dd HH:mm:ss").toString());
        }

        if (userInfoDto != null) {
            queryWrapper.eq("user_id", userInfoDto.getUserId());
        }
        if (!param.getOrderServiceNum().isEmpty()) {
            queryWrapper.like("order_service_num", param.getOrderServiceNum());
        }
        if (param.getOrderServiceState() != null) {
            queryWrapper.eq("order_service_state", param.getOrderServiceState());
        }

        Page<OrderService> page = new Page<>(param.getPageNum(), param.getPageSize());
        orderServiceMapper.selectPage(page, queryWrapper);

        Page<OrderServiceDto> dtoPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
        ArrayList<OrderServiceDto> orderServiceDtos = new ArrayList<>();
        if (page.getRecords() != null) {
            for (OrderService orderService : page.getRecords()) {
                OrderServiceDto orderServiceDto = BeanUtil.toBean(orderService, OrderServiceDto.class);
                //用户信息
                Result<UserInfoDto> userInfoDtoResult = personClient.getByUserId(orderServiceDto.getUserId());
                if (userInfoDtoResult.getCode() != 200) {
                    throw new OrderProductException(userInfoDtoResult.getCode(), userInfoDtoResult.getMsg());
                }
                UserInfoDto dto = userInfoDtoResult.getData();
                orderServiceDto.setUserInfoDto(dto);
                //门店信息
                Result<StoreDto> storeDtoResult = personClient.getStoreById(orderServiceDto.getStoreId());
                if(storeDtoResult.getCode()!=200){
                    throw new WoniuException(userInfoDtoResult.getMsg(), userInfoDtoResult.getCode());
                }
                StoreDto storeDto = storeDtoResult.getData();
                orderServiceDto.setStoreDto(storeDto);
                //服务详情
                List<OrderServiceInfoDto> orderServiceInfoDtos = orderServiceInfoService.selectOrderServiceInfoByOrderServiceNum(orderServiceDto.getOrderServiceNum());
                orderServiceDto.setOrderServiceInfoDtos(orderServiceInfoDtos);
                //获取car信息
                Result<List<CarInfoDto>> listResult = carClient.loadCarInfoById(orderService.getUserId());
                if(listResult.getCode()!=200){
                    throw new WoniuException(listResult.getMsg(),listResult.getCode());
                }
                List<CarInfoDto> carInfoDtos = listResult.getData();
                if(carInfoDtos.size()>0){
                    for (CarInfoDto carInfoDto:carInfoDtos){
                        if(carInfoDto.getCarId().equals(orderServiceDto.getCarId())){
                            orderServiceDto.setCarInfoDto(carInfoDto);
                        }
                    }
                }else {
                    orderServiceDto.setCarInfoDto(null);
                }
                //
                orderServiceDtos.add(orderServiceDto);
            }
            dtoPage.setRecords(orderServiceDtos);
        }
        return dtoPage;
    }

    @Override
    public Page<OrderServiceDto> selectOrderServicesByConditionToUser(OrderServiceQueryConditionParam param) {
        //固定查询用户订单
        QueryWrapper<OrderService> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", param.getUserId());

        Result<UserInfoDto> userInfoDtoResult = personClient.getByUserId(param.getUserId());
        if (userInfoDtoResult.getCode() != 200) {
            throw new OrderProductException(userInfoDtoResult.getCode(), userInfoDtoResult.getMsg());
        }
        UserInfoDto userInfoDto = userInfoDtoResult.getData();

        //按下单时间查询
        if (ObjectUtil.isNotEmpty(param.getOrderMinTime())) {
            queryWrapper.gt("order_time", DateUtil.parse(param.getOrderMinTime(), "yyyy-MM-dd HH:mm:ss").toString());
        }
        if(ObjectUtil.isNotEmpty(param.getOrderMaxTime())){
            queryWrapper.le("order_time",DateUtil.parse(param.getOrderMaxTime(), "yyyy-MM-dd HH:mm:ss").toString());
        }
        if (ObjectUtil.isNotEmpty(param.getPayMinTime())) {
            queryWrapper.gt("pay_time",DateUtil.parse(param.getPayMinTime(), "yyyy-MM-dd HH:mm:ss").toString());
        }
        if(ObjectUtil.isNotEmpty(param.getPayMaxTime())){
            queryWrapper.le("pay_time",DateUtil.parse(param.getPayMaxTime(), "yyyy-MM-dd HH:mm:ss").toString());
        }
        if (!param.getOrderServiceNum().isEmpty()) {
            queryWrapper.like("order_service_num", param.getOrderServiceNum());
        }
        if (param.getOrderServiceState() != null) {
            queryWrapper.eq("order_service_state", param.getOrderServiceState());
            queryWrapper.or();
            queryWrapper.eq("order_service_state",StaticData.ORDER_SERVICE_STATE_DELETED);
        }else {
            queryWrapper.eq("order_service_state",StaticData.ORDER_SERVICE_STATE_DELETED);
        }

        Page<OrderService> page = new Page<>(param.getPageNum(), param.getPageSize());
        orderServiceMapper.selectPage(page, queryWrapper);

        Page<OrderServiceDto> dtoPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
        ArrayList<OrderServiceDto> orderServiceDtos = new ArrayList<>();
        if (page.getRecords() != null) {
            for (OrderService orderService : page.getRecords()) {
                OrderServiceDto orderServiceDto = BeanUtil.toBean(orderService, OrderServiceDto.class);
                //用户信息
                if (userInfoDtoResult.getCode() != 200) {
                    throw new OrderProductException(userInfoDtoResult.getCode(), userInfoDtoResult.getMsg());
                }
                UserInfoDto dto = userInfoDtoResult.getData();
                orderServiceDto.setUserInfoDto(dto);
                //门店信息
                Result<StoreDto> storeDtoResult = personClient.getStoreById(orderServiceDto.getStoreId());
                if(storeDtoResult.getCode()!=200){
                    throw new WoniuException(userInfoDtoResult.getMsg(), userInfoDtoResult.getCode());
                }
                StoreDto storeDto = storeDtoResult.getData();
                orderServiceDto.setStoreDto(storeDto);
                //服务详情
                List<OrderServiceInfoDto> orderServiceInfoDtos = orderServiceInfoService.selectOrderServiceInfoByOrderServiceNum(orderServiceDto.getOrderServiceNum());
                orderServiceDto.setOrderServiceInfoDtos(orderServiceInfoDtos);
                //获取car信息
                Result<List<CarInfoDto>> listResult = carClient.loadCarInfoById(orderService.getUserId());
                if(listResult.getCode()!=200){
                    throw new WoniuException(listResult.getMsg(),listResult.getCode());
                }
                List<CarInfoDto> carInfoDtos = listResult.getData();
                if(carInfoDtos.size()>0){
                    for (CarInfoDto carInfoDto:carInfoDtos){
                        if(carInfoDto.getCarId().equals(orderServiceDto.getCarId())){
                            orderServiceDto.setCarInfoDto(carInfoDto);
                        }
                    }
                }else {
                    orderServiceDto.setCarInfoDto(null);
                }
                //
                orderServiceDtos.add(orderServiceDto);
            }
            dtoPage.setRecords(orderServiceDtos);
        }
        return dtoPage;
    }

    @Override
    public OrderServiceDto selectOrderServiceByOrderServiceNum(String orderServiceNum) {
        //查询数据库
        OrderService orderService = orderServiceMapper.selectById(orderServiceNum);
        if(orderService==null){
            return null;
        }
        OrderServiceDto orderServiceDto = BeanUtil.toBean(orderService, OrderServiceDto.class);

        //补足dto信息
        Result<UserInfoDto> userInfoDtoResult = personClient.getByUserId(orderServiceDto.getUserId());
        if (userInfoDtoResult.getCode() != 200) {
            throw new OrderProductException(userInfoDtoResult.getCode(), userInfoDtoResult.getMsg());
        }
        UserInfoDto userInfoDto = userInfoDtoResult.getData();
        orderServiceDto.setUserInfoDto(userInfoDto);
        Result<StoreDto> storeDtoResult = personClient.getStoreById(orderServiceDto.getStoreId());
        if (storeDtoResult.getCode() != 200) {
            throw new WoniuException(storeDtoResult.getMsg(), storeDtoResult.getCode());
        }
        StoreDto storeDto = storeDtoResult.getData();
        orderServiceDto.setStoreDto(storeDto);
        //查询订单清单
        List<OrderServiceInfoDto> orderServiceInfoDtos = orderServiceInfoService.selectOrderServiceInfoByOrderServiceNum(orderServiceNum);
        orderServiceDto.setOrderServiceInfoDtos(orderServiceInfoDtos);
        //获取car信息
        Result<List<CarInfoDto>> listResult = carClient.loadCarInfoById(orderService.getUserId());
        if(listResult.getCode()!=200){
            throw new WoniuException(listResult.getMsg(),listResult.getCode());
        }
        List<CarInfoDto> carInfoDtos = listResult.getData();
        if(carInfoDtos.size()>0){
            for (CarInfoDto carInfoDto:carInfoDtos){
                if(carInfoDto.getCarId().equals(orderServiceDto.getCarId())){
                    orderServiceDto.setCarInfoDto(carInfoDto);
                }
            }
        }else {
            orderServiceDto.setCarInfoDto(null);
        }
        return orderServiceDto;
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public Boolean updateOrderServiceReviewStateByOrderServiceNum(String orderServiceNum) {
        OrderService orderService = orderServiceMapper.selectById(orderServiceNum);
        if (orderService == null) {
            throw new OrderProductException(OrderProductExceptionCode.ORDER_NULL);
        }
        orderService.setReviewState(StaticData.ORDER_PRODUCT_REVIEW_STATE_FINISHED);

        //执行修改
        orderServiceMapper.updateById(orderService);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public Boolean cancelOrder(String orderServiceNum, String userId) {
        OrderService orderService = orderServiceMapper.selectById(orderServiceNum);

        //判断订单是否存在
        if (orderService == null) {
            throw new OrderServiceException(OrderServiceExceptionCode.ORDER_NULL);
        }
        //判断登录用户是否有权取消
        if (!orderService.getUserId().equals(userId)) {
            throw new OrderServiceException(OrderServiceExceptionCode.ORDER_SERVICE_USER_NO_POWER);
        }
        //订单是否能够取消
        if (!orderService.getOrderServiceState().equals(StaticData.ORDER_SERVICE_STATE_NO_PAID)) {
            throw new OrderServiceException(OrderServiceExceptionCode.ORDER_SERVICE_STATE_NOT_CANCEL);
        }

        //订单执行取消
        orderService.setOrderServiceState(StaticData.ORDER_SERVICE_STATE_CANCEL);
        orderServiceMapper.updateById(orderService);

        //因不需要，服务订单所使用的商品材料归库
        OrderServiceDto orderServiceDto = selectOrderServiceByOrderServiceNum(orderServiceNum);
        for (OrderServiceInfoDto orderServiceInfoDto:orderServiceDto.getOrderServiceInfoDtos()){
            PutStorageForm putStorageForm = new PutStorageForm();
            putStorageForm.setNum(orderServiceInfoDto.getNum());
            putStorageForm.setSpInfoId(orderServiceInfoDto.getSpInfoId());
            productClient.putStorageTwo(putStorageForm);
        }
        //减除积分
        personClient.reduceUserScore(orderServiceDto.getUserId(),Integer.valueOf(orderServiceDto.getOrderPrice().toString()),StaticData.SCORE_SHOPPING);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public Boolean deleteOrder(String orderServiceNum, String userId) {
        OrderService orderService = orderServiceMapper.selectById(orderServiceNum);

        //判断订单是否存在
        if (orderService != null) {
            throw new OrderServiceException(OrderServiceExceptionCode.ORDER_NULL);
        }
        //判断登录用户是否有权取消
        if (!orderService.getUserId().equals(userId)) {
            throw new OrderServiceException(OrderServiceExceptionCode.ORDER_SERVICE_USER_NO_POWER);
        }
        //判断订单是否能删除
        if (!orderService.getOrderServiceState().equals(StaticData.ORDER_SERVICE_STATE_CANCEL) || !orderService.getOrderServiceState().equals(StaticData.ORDER_SERVICE_STATE_FINISHED)) {
            throw new OrderServiceException(OrderServiceExceptionCode.ORDER_SERVICE_STATE_NO_DELETED);
        }

        //执行删除
        orderService.setOrderServiceState(StaticData.ORDER_SERVICE_STATE_DELETED);
        orderServiceMapper.updateById(orderService);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public Boolean orderService(OrderServiceAddParam param, String token) {
        //(服务订单编号)雪花数随机生成商品编号 日期转换器
        String orderServiceNum = new Snowflake(1, 1).nextIdStr();

        //查询门店管理员
        Result<StoreAdminDto> storeAdminDtoResult = personClient.getStoreAdminInfoById(param.getStoreAdminId());
        if (storeAdminDtoResult.getCode() != 200) {
            throw new WoniuException(storeAdminDtoResult.getMsg(), storeAdminDtoResult.getCode());
        }
        //查询门店信息
        Result<StoreDto> storeDtoResult = personClient.getStoreById(storeAdminDtoResult.getData().getStoreId());
        if (storeDtoResult.getCode() != 200) {
            throw new WoniuException(storeDtoResult.getMsg(), storeDtoResult.getCode());
        }
        StoreDto storeDto = storeDtoResult.getData();

        //预备获取orderPrice
        BigDecimal orderPrice = BigDecimal.valueOf(0.00);
        //查询serviceInfos并新增订单详情，门店商品 带验证
        for (ServiceAndProductListForm form : param.getServiceIdAndProductIdList()) {
            //查询服务
            Result<ServiceInfoDto> serviceInfoDtoResult = productClient.findServiceInfoById(form.getServiceId());
            if (serviceInfoDtoResult.getCode() != 200) {
                throw new WoniuException(serviceInfoDtoResult.getMsg(), serviceInfoDtoResult.getCode());
            }
            ServiceInfoDto serviceInfoDto = serviceInfoDtoResult.getData();
            //判断服务是否属于门店
            if (!serviceInfoDto.getStoreId().equals(storeDto.getStoreId())) {
                throw new OrderServiceException(OrderServiceExceptionCode.SERVICE_NO_EQUAL_STORE);
            }

            if(serviceInfoDto.getSTName().contains("洗车")){
                OrderServiceInfo orderServiceInfo = new OrderServiceInfo();
                orderServiceInfo.setOrderServiceNum(orderServiceNum);
                orderServiceInfo.setServiceId(serviceInfoDto.getServiceId());
                orderServiceInfo.setSpInfoId(0);
                orderServiceInfo.setNum(0);
                orderServiceInfo.setFinalBasePrice(serviceInfoDto.getServiceBasePrice());
                //新增orderServiceInfo
                orderServiceInfoMapper.insert(orderServiceInfo);
                //计入总价
                orderPrice=orderPrice.add(serviceInfoDto.getServiceBasePrice());
            }else {
                //查询门店商品
                Result<StoreProductDto> oneStoreProductResult = productClient.findOneStoreProductById(form.getSpInfoId());
                if (oneStoreProductResult.getCode() != 200) {
                    throw new WoniuException(oneStoreProductResult.getMsg(), oneStoreProductResult.getCode());
                }
                StoreProductDto storeProductDto = oneStoreProductResult.getData();
                if (!storeProductDto.getStoreId().equals(storeDto.getStoreId())) {
                    throw new OrderServiceException(OrderServiceExceptionCode.STORE_PRODUCT_NO_EQUAL_STORE);
                }
                //判断商品是否删除
                if (storeProductDto == null || storeProductDto.getSpInfoState().equals(StaticData.STORE_PRODUCT_INFO_STATE_DELETE)) {
                    throw new OrderServiceException(OrderServiceExceptionCode.STORE_PRODUCT_NO_EXISTED_OR_DELETED);
                }
                //判断库存是否不足
                if (storeProductDto.getRestNum().compareTo(BigDecimal.valueOf(form.getRestNum())) < 0) {
                    throw new OrderServiceException(OrderServiceExceptionCode.STORE_PRODUCT_NUM_SHUT);
                }
                OrderServiceInfo orderServiceInfo = new OrderServiceInfo();
                orderServiceInfo.setOrderServiceNum(orderServiceNum);
                orderServiceInfo.setServiceId(serviceInfoDto.getServiceId());
                orderServiceInfo.setNum(form.getRestNum());
                orderServiceInfo.setSpInfoId(storeProductDto.getSpInfoId());
                //计算单个服务最终费用
                BigDecimal finalBasePrice = BigDecimal.valueOf(0.00);
                finalBasePrice=finalBasePrice.add(serviceInfoDto.getServiceBasePrice()).add(storeProductDto.getStorePrice().multiply(BigDecimal.valueOf(orderServiceInfo.getNum())));
                orderServiceInfo.setFinalBasePrice(finalBasePrice);
                //新增orderServiceInfo
                orderServiceInfoMapper.insert(orderServiceInfo);
                //计入总价
                orderPrice=orderPrice.add(finalBasePrice);
                //减少库存
                OutStorageForm outStorageForm = new OutStorageForm();
                outStorageForm.setNum(orderServiceInfo.getNum());
                outStorageForm.setSpInfoId(orderServiceInfo.getSpInfoId());
                Result<Boolean> outStorageResult = productClient.outStorageTwo(outStorageForm);
                if (oneStoreProductResult.getCode() != 200) {
                    new WoniuException(oneStoreProductResult.getMsg(), outStorageResult.getCode());
                }
            }
        }

        //查询用户是否存在
        Result<UserInfoDto> userInfoDtoResult = personClient.getByUserId(param.getUserId());
        if (userInfoDtoResult.getCode() != 200) {
            throw new WoniuException(userInfoDtoResult.getMsg(), userInfoDtoResult.getCode());
        }
        UserInfoDto userInfoDto = userInfoDtoResult.getData();
        //查询车辆并加以判断
        Result<List<CarInfoDto>> listResult = carClient.loadCarInfoById(userInfoDto.getUserId());
        if(listResult.getCode()!=200){
            throw new WoniuException(listResult.getMsg(),listResult.getCode());
        }
        //判断车辆是否属于订单用户
        List<CarInfoDto> carInfoDtos = listResult.getData();
        boolean bool=false;
        for (CarInfoDto carInfoDto:carInfoDtos){
            if(!carInfoDto.getCarId().equals(param.getCarId())){
                bool=true;
            }
        }
        if(bool){
            throw new CarException(CarExceptionCode.CAR_INFO_NO_EQUAL_USER);
        }
        //最终新增订单
        OrderService orderService = new OrderService();
        orderService.setOrderServiceNum(orderServiceNum);
        orderService.setOrderServiceState(StaticData.ORDER_SERVICE_STATE_NO_PAID);
        orderService.setUserId(userInfoDto.getUserId());
        orderService.setCarId(param.getCarId());
        orderService.setStoreId(storeDto.getStoreId());
        orderService.setOrderTime(LocalDateTimeUtil.parse(param.getOrderTime(), "yyyy-MM-dd HH:mm:ss"));
        orderService.setOrderPrice(orderPrice);
        orderService.setReviewState(StaticData.ORDER_PRODUCT_REVIEW_STATE_NO);
        orderServiceMapper.insert(orderService);

        //延迟队列
        rabbitTemplate.convertAndSend("order_service_del_delay_queue",orderServiceNum);
        return true;
    }

    @Transactional(rollbackFor = Throwable.class)
    @Override
    public String payByCommon(String orderServiceNum, String userId, String token) throws Exception {
        OrderServiceDto orderServiceDto = selectOrderServiceByOrderServiceNum(orderServiceNum);
        if (orderServiceDto == null) {
            throw new OrderServiceException(OrderServiceExceptionCode.ORDER_NULL);
        }
        if (!orderServiceDto.getOrderServiceState().equals(StaticData.ORDER_PRODUCT_STATE_NO_PAID)) {
            throw new OrderServiceException(OrderServiceExceptionCode.ORDER_SERVICE_PAID);
        }
        if (!orderServiceDto.getUserId().equals(userId)) {
            throw new OrderServiceException(OrderServiceExceptionCode.ORDER_SERVICE_USER_NO_POWER);
        }

        //调用
        PagePayParam payParam = new PagePayParam();
        //以下参数根据实际情况设置
        payParam.setOrderId(UUID.randomUUID().toString().replace("-", ""));
        payParam.setSubject("汽车服务");
        payParam.setBody("汽车服务订单支付");
        payParam.setOrderId(orderServiceNum);
        payParam.setMoney(orderServiceDto.getOrderPrice().doubleValue());
        payParam.setReturnUrl("http://localhost:80/swagger-ui.html");
        //内网穿透 记得修改
        payParam.setNotifyUrl(" http://h5mdc4.natappfree.cc/order/orderService/payNotify");
        //取出数据库订单的下单时间
        System.out.println("下单时间" + orderServiceDto.getOrderTime());
        LocalDateTime localDateTime = orderServiceDto.getOrderTime();
        long expireTime = java.sql.Date.from(localDateTime.plusMinutes(15).atZone(ZoneId.systemDefault()).toInstant()).getTime();
        long now = new java.util.Date().getTime();
        int minute = (int) ((expireTime - now) / 1000 / 60);
        System.out.println(expireTime + " " + minute);
        if (minute < 1) {
            throw new OrderProductException(45566, "订单超时");
        }
        java.util.Date date = new java.util.Date(expireTime);
        String expire = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
        payParam.setTimeExpire(expire);

        //调用接口
        String pay = alipayUtil.pagePay(payParam);
        return pay;
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void payNotify(Map<String, String> params) throws AlipayApiException {
        //在异步回调业务层验签 防止伪造请求
        System.out.println("params:" + params);
        boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayConfiguration.getAlipayPublicKey(), "utf-8", "RSA2"); //调用SDK验证签名
        if (signVerified) {
            //验签通过
            //取出订单编号
            String orderServiceNum = params.get("out_trade_no");
            OrderServiceDto orderServiceDto = selectOrderServiceByOrderServiceNum(orderServiceNum);
            String tradeStatus = params.get("trade_status");
            if (orderServiceDto.getOrderServiceState().equals(StaticData.ORDER_SERVICE_STATE_NO_PAID)) {
                orderServiceDto.setOrderServiceState(StaticData.ORDER_SERVICE_STATE_PAID);
                String payTimeStr = params.get("gmt_payment");
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                LocalDateTime payTime = LocalDateTime.parse(payTimeStr, formatter);
                orderServiceDto.setPayTime(payTime);

                //用户积分
                personClient.addUserScore(orderServiceDto.getUserId(),orderServiceDto.getOrderPrice().intValue(),StaticData.SCORE_SHOPPING);
                OrderService orderService = BeanUtil.toBean(orderServiceDto, OrderService.class);
                //改状态
                orderServiceMapper.updateById(orderService);
                //增流程
                for (OrderServiceInfoDto orderServiceInfoDto:orderServiceDto.getOrderServiceInfoDtos()){
                    extraClient.addOrderStream(orderServiceNum,orderServiceDto.getUserId(),orderServiceInfoDto.getServiceInfoDto().getStoreId(),orderServiceInfoDto.getServiceInfoDto().getStreamId(),orderServiceInfoDto.getServiceId());
                }
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public String payByVip(String orderServiceNum, String userId) throws Exception {
        OrderServiceDto orderServiceDto = selectOrderServiceByOrderServiceNum(orderServiceNum);
        if (orderServiceDto == null) {
            throw new OrderServiceException(OrderServiceExceptionCode.ORDER_NULL);
        }
        if (!orderServiceDto.getOrderServiceState().equals(StaticData.ORDER_PRODUCT_STATE_NO_PAID)) {
            throw new OrderServiceException(OrderServiceExceptionCode.ORDER_SERVICE_PAID);
        }
        if (!orderServiceDto.getUserId().equals(userId)) {
            throw new OrderServiceException(OrderServiceExceptionCode.ORDER_SERVICE_USER_NO_POWER);
        }

        //获取用户的vip信息
        Result<UserVipDto> userVipDtoResult = valueAddedClient.getUserVipInfo(userId);
        if(userVipDtoResult.getCode()!=200){
            throw new WoniuException(userVipDtoResult.getMsg(),userVipDtoResult.getCode());
        }
        UserVipDto userVipDto = userVipDtoResult.getData();
        if(!ObjectUtil.isNotEmpty(userVipDto)){
            throw new OrderServiceException(OrderServiceExceptionCode.ORDER_SERVICE_USER_NO_HAVE_VIP);
        }
        //判断是否还有免费洗车次数
        LocalDateTime local = LocalDateTime.now();
        if(userVipDto.getFreeNum()>0&&userVipDto.getVipEndTime().compareTo(local)>0){
            for (OrderServiceInfoDto orderServiceInfoDto:orderServiceDto.getOrderServiceInfoDtos()){
                if(orderServiceInfoDto.getServiceInfoDto().getSTName().contains("洗车")){
                    if(orderServiceInfoDto.getFinalBasePrice().compareTo(BigDecimal.valueOf(0))<=0){
                        break;
                    }
                    System.out.println("过");
                    orderServiceDto.setOrderPrice(orderServiceDto.getOrderPrice().subtract(orderServiceInfoDto.getFinalBasePrice()));
                    OrderService orderService = BeanUtil.toBean(orderServiceDto, OrderService.class);
                    orderServiceMapper.updateById(orderService);
                    orderServiceInfoDto.setFinalBasePrice(BigDecimal.valueOf(0.00));
                    OrderServiceInfo orderServiceInfo = BeanUtil.toBean(orderServiceInfoDto, OrderServiceInfo.class);
                    orderServiceInfoMapper.update(orderServiceInfo,new QueryWrapper<OrderServiceInfo>().eq("order_service_num",orderServiceInfo.getOrderServiceNum()).eq("service_id",orderServiceInfo.getServiceId()));
                    //减少vip免费次数
                    valueAddedClient.reduceFreeNum(userId);
                    break;
                }
            }
        }else {
            throw new OrderServiceException(OrderServiceExceptionCode.ORDER_SERVICE_USER_NO_HAVE_VIP);
        }

        if(orderServiceDto.getOrderPrice().compareTo(BigDecimal.valueOf(0.00))<=0){
            if (orderServiceDto.getOrderServiceState().equals(StaticData.ORDER_SERVICE_STATE_NO_PAID)) {
                orderServiceDto.setOrderServiceState(StaticData.ORDER_SERVICE_STATE_PAID);
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                LocalDateTime payTime =LocalDateTime.now();
                orderServiceDto.setPayTime(payTime);

                //用户积分
                personClient.addUserScore(orderServiceDto.getUserId(),orderServiceDto.getOrderPrice().intValue(),StaticData.SCORE_SHOPPING);
                OrderService orderService = BeanUtil.toBean(orderServiceDto, OrderService.class);
                //改状态
                orderServiceMapper.updateById(orderService);
                //增流程
                for (OrderServiceInfoDto orderServiceInfoDto:orderServiceDto.getOrderServiceInfoDtos()){
                    extraClient.addOrderStream(orderServiceNum,orderServiceDto.getUserId(),orderServiceInfoDto.getServiceInfoDto().getStoreId(),orderServiceInfoDto.getServiceInfoDto().getStreamId(),orderServiceInfoDto.getServiceId());
                }
            }
            return "支付成功";
        }

        //调用
        PagePayParam payParam = new PagePayParam();
        //以下参数根据实际情况设置
        payParam.setOrderId(UUID.randomUUID().toString().replace("-", ""));
        payParam.setSubject("汽车服务");
        payParam.setBody("汽车服务订单支付");
        payParam.setOrderId(orderServiceNum);
        payParam.setMoney(orderServiceDto.getOrderPrice().doubleValue());
        payParam.setReturnUrl("http://localhost:80/swagger-ui.html");

        //内网穿透 记得修改
        payParam.setNotifyUrl(" http://h5mdc4.natappfree.cc/order/orderService/payNotify");
        //取出数据库订单的下单时间
        System.out.println("下单时间" + orderServiceDto.getOrderTime());
        LocalDateTime localDateTime = orderServiceDto.getOrderTime();
        long expireTime = java.sql.Date.from(localDateTime.plusMinutes(15).atZone(ZoneId.systemDefault()).toInstant()).getTime();
        long now = new java.util.Date().getTime();
        int minute = (int) ((expireTime - now) / 1000 / 60);
        System.out.println(expireTime + " " + minute);
        if (minute < 1) {
            throw new OrderProductException(45566, "订单超时");
        }
        java.util.Date date = new java.util.Date(expireTime);
        String expire = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
        payParam.setTimeExpire(expire);

        //调用接口
        String pay = alipayUtil.pagePay(payParam);
        return pay;
    }

    @Override
    public Boolean updateOrderServiceStateByOrderNum(String orderNum) {
        OrderServiceDto orderServiceDto = selectOrderServiceByOrderServiceNum(orderNum);
        if(orderServiceDto==null){
            throw new OrderServiceException(OrderServiceExceptionCode.ORDER_NULL);
        }
        OrderService orderService = orderServiceMapper.selectById(orderNum);
        if(orderServiceDto.getOrderServiceState().equals(StaticData.ORDER_SERVICE_STATE_NO_PAID)){
            throw new OrderServiceException(OrderServiceExceptionCode.ORDER_SERVICE_STATE_NO_PAID);
        }else if (orderServiceDto.getOrderServiceState().equals(StaticData.ORDER_SERVICE_STATE_PAID)){
            orderService.setOrderServiceState(StaticData.ORDER_SERVICE_STATE_RUNNING);
        } else if(orderServiceDto.getOrderServiceState().equals(StaticData.ORDER_SERVICE_STATE_RUNNING)){
            Result<List<OrderStreamDto>> orderStreamsResult= extraClient.getOrderStreamByNum(orderNum);
            if(orderStreamsResult.getCode()!=200){
                throw new WoniuException(orderStreamsResult.getMsg(),orderStreamsResult.getCode());
            }
            boolean streamFlag=false;
            int streamTime=0;
            List<OrderStreamDto> orderStreamDtoList = orderStreamsResult.getData();
            Iterator<OrderStreamDto> iterator = orderStreamDtoList.iterator();
            while (iterator.hasNext()){
                OrderStreamDto dto = iterator.next();
                if(dto.getOrderStreamState2().equals(1)){
                    streamFlag=true;
                }
                if(streamFlag){
                    streamTime=streamTime+1;
                }
            }
            if(streamTime==1){
                orderService.setOrderServiceState(StaticData.ORDER_SERVICE_STATE_FINISHED);
            }else {
                throw new OrderServiceException(OrderServiceExceptionCode.ORDER_SERVICE_STATE_RUNNING);
            }
        }else {
            throw new OrderServiceException(OrderServiceExceptionCode.ORDER_CANCELED_OR_DELETED);
        }

        orderServiceMapper.updateById(orderService);
        return true;
    }

    @Override
    public String finishOrderState(String orderNum) {
        OrderServiceDto orderServiceDto = selectOrderServiceByOrderServiceNum(orderNum);
        if(orderServiceDto==null){
            throw new OrderServiceException(OrderServiceExceptionCode.ORDER_NULL);
        }
        OrderService orderService = BeanUtil.toBean(orderServiceDto, OrderService.class);
        orderService.setOrderServiceState(StaticData.ORDER_SERVICE_STATE_FINISHED);
        orderServiceMapper.updateById(orderService);
        return orderService.getOrderServiceNum();
    }
}
